package com.semac.client.componentes.combo;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HasName;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.Widget;

/**
 * Wrapper class for the available ListBox from gwt.<br>
 * This class improves a little bit the connection between UI classes
 * and presenter classes, adding an interface of type HasValuesList
 * thus hiding widget classes from the presenter class<br>
 * <br>
 * For more information about GWT MVP, see <br>
 * http://code.google.com/intl/pt-BR/webtoolkit/articles/mvp-architecture.html<br>
 * 
 * @author Martin Reus
 *
 */
public class Combo extends Composite implements HasValuesList, HasComboValueChangeHandler, HasName, ChangeHandler{

	private static ComboUiBinder uiBinder = GWT.create(ComboUiBinder.class);
	@UiField ListBox comboBox;
	@UiField Label titleLabel;
	private String name = "";
	private String defaultValue = "";
	private HandlerManager eventBus;

	
	private Integer minValue = 0;
	private Integer maxValue = 0;
	private Integer increment = 0;
	private String sufixo = "";
		
	
	interface ComboUiBinder extends UiBinder<Widget, Combo> {
	}

	public Combo() {
		this.eventBus = new HandlerManager(this);
		initWidget(uiBinder.createAndBindUi(this));
		//when using simple constructor (and not UIBinder) set a default name for the combo
//		this.setName("Combo");
		this.comboBox.addChangeHandler(this);
//		this.updateIntervalsAndComboBoxValues();
	}


	@Override
	public void clear() {
		this.comboBox.clear();
		this.setDefault(this.defaultValue);
	}

	@Override
	public void addItem(String item) {
		this.comboBox.addItem(item);
	}

	@Override
	public void removeItem(String item) {
		for (int i = 0 ; i < this.comboBox.getItemCount() ; i++) {
			if (this.comboBox.getItemText(i).equals(item)){
				this.comboBox.removeItem(i);
			}
		}
	}

	public String getSelectedItemAsString(){
		String item = pegaValorSelecionadoDoComboSemSufixo();
		if (item == null || item.equals("") || item.equals(this.defaultValue))
			return null;
		else
			return item;
	}
	
	
	public Integer getSelectedItemAsInteger(){
		String item = pegaValorSelecionadoDoComboSemSufixo();
		if (item == null || item.equals("") || item.equals(this.defaultValue))
			return null;
		else
			try{
				return Integer.parseInt(item);
			}catch (Exception e) {
				return null;
			}		
	}
	
	
	@Override
	public void removeItem(Integer itemIndex) {
		this.comboBox.removeItem(itemIndex);
	}

	@Override
	public String getItem(Integer itemIndex) {
		return this.comboBox.getItemText(itemIndex);
	}

	@Override
	public void setName(String name) {
		this.name = name;
		this.titleLabel.setText(name);
	}

	@Override
	public String getName() {
		return this.name;
	}

	@Override
	public HandlerRegistration addComboValueChangedHandlerRegistration(ComboValueChangeHandler handler) {
		return this.eventBus.addHandler(ComboValueChangedEvent.TYPE, handler);
	}


	@Override
	public void onChange(ChangeEvent event) {
		String selectedString = pegaValorSelecionadoDoComboSemSufixo();
		if (selectedString.equals(this.defaultValue))
			this.eventBus.fireEvent(new ComboValueChangedEvent(""));
		else
			this.eventBus.fireEvent(new ComboValueChangedEvent(selectedString));
		
	}
	
	public boolean isEnabled(){
		return this.comboBox.isEnabled();
	}
	
	public void setEnabled(boolean enabled){
		this.comboBox.setEnabled(enabled);
	}
	
	public void setDefault(String defaultValue){
		this.defaultValue  = defaultValue;
		if (this.comboBox.getItemCount() == 0)
			this.comboBox.addItem(this.defaultValue);
		else
			this.comboBox.setItemText(0, this.defaultValue);
	}
	
	public void setIncrement(Integer increment){
		if (increment == 0)
			increment = 1;
		this.increment = increment;
		this.updateIntervalsAndComboBoxValues();
	}
	
	public void setLowerLimit(Integer lowerLimit){
		this.minValue = lowerLimit;
		this.updateIntervalsAndComboBoxValues();
	}
	
	
	public void setUpperLimit(Integer upperLimit){
		this.maxValue = upperLimit;
		this.updateIntervalsAndComboBoxValues();
	}
	
	public void setSufixo(String sufixo){
		this.sufixo = sufixo;
		if (!this.sufixo.trim().equals(""))
			this.sufixo = " " + this.sufixo;
		this.updateIntervalsAndComboBoxValues();
	}
	
	
	
	private String valorComboSemSufixo(Integer index){
		String valor = "";
		String item = this.comboBox.getItemText(index);
		
		if (!this.sufixo.trim().equals("") && !item.equals(this.defaultValue)){
			String[] partes = item.split(this.sufixo);			
			try{
				valor = partes[0];
			}catch (Exception e) {
			}
		}else{
			valor = item;
		}
		return valor;
	}
	
	
	private String pegaValorSelecionadoDoComboSemSufixo(){				
		return this.valorComboSemSufixo(this.comboBox.getSelectedIndex());
	}
	
	
	/**
	 * Constructs the values for the combobox and adds it to the UI.
	 */
	private void updateIntervalsAndComboBoxValues(){
		String comboString = "";
//		Integer highBound = 0;
		Integer lowBound = this.minValue;
		
		this.comboBox.clear();
		
		this.comboBox.addItem(defaultValue);
				
		///calculate the incremet used for each range of values
		//this.increment = (this.maxValue - this.minValue) / this.intervals;	
		if (this.increment == 0)
			this.increment = 1; // to avoid infinite loop
	
		while ( lowBound < this.maxValue){

			comboString = lowBound + " " + sufixo;
						
			//add the range string to the combo box
			this.comboBox.addItem(comboString);

			lowBound += this.increment;
		}
		
		comboString = this.maxValue + sufixo;		
		//add the range string to the combo box
		this.comboBox.addItem(comboString);
		
		
		
		this.comboBox.setSelectedIndex(0);
	}
	

	public void setItemSelected(String item){
		if (item == null || item.trim().equals(""))
			this.comboBox.setSelectedIndex(0);
		for (int i = 0 ; i < this.comboBox.getItemCount() ; i++) {
			if (this.valorComboSemSufixo(i).equals(item)){
				this.comboBox.setSelectedIndex(i);
				break;
			}
		}
	}
	
	
}
